<?php

// Namespace

namespace Snsfg;

//require_once(PATH_APPLICATION . 'Component/php/SocketLog.class.php');


/**
 * CSocialNetworkAccount is a class that can be used to manage social network accounts
 *
 * @package		Snsfg
 * @category	Model
 */

class CAccount extends \Loop\CObject
{
	
	/**
	 *
	 */

	public function api_completeConnection()
	{
		// Get API arguments

		//$payload = json_decode(fv('payload', true), true);

		$accountId = fv('accountId',true);
		$accountReference = fv('accountReference');


		// Load the object

		$this->loadSecure
		(
			$accountId,
			$accountReference,
			null,
			array('acceptTemporaryObjects' => true)
		);


		// Call the method

		$result = $this->completeConnection();

		redirect($result);
	}


	/**
	 *
	 */

	public function api_getGroups()
	{
		$payload = json_decode(fv('payload', true), true);

		$result = array();

		$rawAccounts = $this->find
		(
			array
			(
				'conditions' => array
				(
					'wechatAppId' => array(EQUAL, $payload['appId']),
					'universe' => array(EQUAL, $payload['ef_universe_id']),
					'socialNetwork' => array(EQUAL, $payload['sns'])
				)
			)
		);

		
		$rawAccount = array_pop($rawAccounts);

		$this->loadFromRawObject($rawAccount);

		$result = $this->getSocialNetworkDriver()->getGroups($this);
		
		echo $this->JSON($result);
		exit;
	}


	/**
	 *
	 */

	public function api_getSocials()
	{
		
		$payload = json_decode(fv('payload', true), true);

		$universe = $payload['ef_universe_id'];
		$result = array();

		if(isset($payload['ef_user_id']) && $payload['ef_user_id'])
		{
			$efId = $payload['ef_user_id'];
		}
		else
		{
			$efId = '*';
		}

		$rawSocials = $this->find
		(
			array
			(
				'conditions' => array
				(
					'efId' => array(
							LOOP_OR,
							array(
								array(EQUAL, $efId),
								array(EQUAL, '*')
							)
						),
					'universe' => array(EQUAL, $universe)
				)
			)
		);

		foreach ($rawSocials as $key => $rawSocial) {
			$result[$key]['sns'] = $rawSocial['socialNetwork'];
			$result[$key]['screenName'] = $rawSocial['screenName'];
			$result[$key]['appId'] = $rawSocial['internalId']?$rawSocial['internalId']:$rawSocial['wechatAppId'];
		}

		echo json_encode($result, JSON_FORCE_OBJECT);
		exit;
	}


	/*
	 *
	 */

	public function api_getStatistics()
	{
		$result = array();

		$payload = json_decode(fv('payload', true), true);

		require_once(PATH_APPLICATION . 'Model/CPostStatus.php');

		$status = new CPostStatus();

		$rawStatuses = $status->find(
					array
					(
						'conditions' => array
						(
							'universe' => array(EQUAL,  $payload['ef_universe_id']),
							'socialNetwork' => array(EQUAL,  $payload['sns']),
							'sendingId' => array(EQUAL,  $payload['ef_sending_id'])
						)
					)
			);

		if(empty($rawStatuses))
		{
			$result['errcode'] = -2;
			$result['errmsg'] = 'Not found this sending ID';
			$result['ef_sending_id'] = $payload['ef_sending_id'];

			echo json_encode($result);
			exit;
		}

		$rawStatus = array_pop($rawStatuses);

		if($rawStatus['internalId'])
		{
			require_once(PATH_APPLICATION . 'Model/CWechat.php');

			$wechat = new CWechat();

			$rawStatistic = $wechat->getResponse($rawStatus['internalId']);
			
			if(isset($rawStatistic['event']) && $rawStatistic['event'] == 'MASSSENDJOBFINISH')
			{
				$result['errcode'] = 0;
				$result['errmsg'] = 'Statistics avaiable';
				$result['ef_sending_id'] = $payload['ef_sending_id'];
				$result['creation_ts'] = $rawStatistic['createTime'];
				$result['msgtype'] = $rawStatus['type'];
				$result['status'] = $rawStatistic['status'];
				$result['total'] = $rawStatistic['totalCount'];
				$result['filter'] = $rawStatistic['filterCount'];
				$result['sent'] = $rawStatistic['sentCount'];
				$result['error'] = $rawStatistic['errorCount'];
			}
			else
			{
				$result['errcode'] = -1;
				$result['errmsg'] = 'Not yet receive statistics';
				$result['ef_sending_id'] = $payload['ef_sending_id'];
			}

		}
		else
		{
			$result = json_decode($rawStatus['discription'], true);
		}
		
		echo json_encode($result);
		exit;
		
	}


	/**
	 *
	 */

	public function api_getStatuses()
	{
		// Get API arguments

		$payload = json_decode(fv('payload', true));

		$accountId = $payload['accountId'];
		$accountReference = $payload['accountReference'];

		// Load the Object

		$this->loadSecure($accountId, $accountReference);

		$result = $this->getStatuses();

		return $result;
	}



	/**
	 *
	 */

	public function api_getSnsUsers()
	{
		$payload = json_decode(fv('payload', true), true);

		$result = array();

		$rawAccounts = $this->find
		(
			array
			(
				'conditions' => array
				(
					'wechatAppId' => array(EQUAL, $payload['appId']),
					'universe' => array(EQUAL, $payload['ef_universe_id']),
					'socialNetwork' => array(EQUAL, $payload['sns'])
				)
			)
		);

		
		$rawAccount = array_pop($rawAccounts);

		$this->loadFromRawObject($rawAccount);

		$result = $this->getSocialNetworkDriver()->getSnsUsers($this);
		
		echo $this->JSON($result);
		exit;
	}


	/**
	 *
	 */

	public function api_getSnsUserInfo()
	{
		$payload = json_decode(fv('payload', true), true);

		$result = array();

		$rawAccounts = $this->find
		(
			array
			(
				'conditions' => array
				(
					'wechatAppId' => array(EQUAL, $payload['appId']),
					'universe' => array(EQUAL, $payload['ef_universe_id']),
					'socialNetwork' => array(EQUAL, $payload['sns'])
				)
			)
		);

		
		$rawAccount = array_pop($rawAccounts);

		$this->loadFromRawObject($rawAccount);

		$result = $this->getSocialNetworkDriver()->getSnsUserInfo($this, $payload['openId']);
		
		echo $this->JSON($result);
		exit;
	}


	/**
	 *
	 */
	
	public function api_postStatus()
	{
		//Get API arguments
		$fvPayload = fv('payload');
		if($fvPayload == '')
		{
			echo '{"error":"-3","errmsg":" \'payload\' not defined or it is null"}';
			exit;
		}


		// slog('The payload What SNSGW received:');
		// slog($fvPayload);
				
    	$payload = str_replace("\r\n", '', $fvPayload);

		$payload = json_decode(fv('payload', true), true);


		// slog('payload array:');
		// slog($payload);
		

		if($payload == NULL)
		{
			echo '{"error":"-4","errmsg":" The\'payload\' is a illegal JSON","payload":'.$fvPayload.'}';
			exit;
		}

		

		$errmsgs = array();

		if(isset($payload['sns']) && $payload['sns'] == SOCIAL_NETWORK_WECHAT)
		{
			if(isset($payload['msgtype']) && $payload['msgtype'] == 'mpnews')
			{
				if(!isset($payload['articles']) || $payload['articles'] == ''){
					$errmsgs['articles'] = array('errcode'=>'-6','errmsg' => 'Not found articles');
				}
			}
			else if(isset($payload['msgtype']) && $payload['msgtype'] == 'text')
			{
				if(!isset($payload['content']) || $payload['content'] == ''){
					$errmsgs['articles'] = array('errcode'=>'-11','errmsg' => 'Not found content');
				}
			}

			if(!isset($payload['ef_sending_id']) || $payload['ef_sending_id'] == ''){
				$errmsgs['ef_sending_id'] = array('errcode'=>'-7','errmsg' => 'Not found ef_sending_id');
			}
			if(!isset($payload['group_id']) || $payload['group_id'] == ''){
				$errmsgs['group_id'] = array('errcode'=>'-8','errmsg' => 'Not found group_id');
			}
			if(!isset($payload['ef_universe_id']) || $payload['ef_universe_id'] == ''){
				$errmsgs['ef_universe_id'] = array('errcode'=>'-9','errmsg' => 'Not found ef_universe_id');
			}
			if(!isset($payload['msgtype']) || $payload['msgtype'] == ''){
				$errmsgs['msgtype'] = array('errcode'=>'-10','errmsg' => 'Not found msgtype');
			}
		}
		else
		{
			$errmsgs['sns'] = array('errcode'=>'-5','errmsg' => 'Not found sns');
		}

		if(!empty($errmsgs))
		{
			echo json_encode($errmsgs);
			exit;
		}




		$messageData = array();

		if(strtolower(trim($payload['sns'])) == SOCIAL_NETWORK_WECHAT)
		{
			$messageData['payload'] = $payload;
		}
		else
		{
			$messageData['content'] = $payload['content'];
			$messageData['link'] = $payload['link'];

			$messageData['content'] .= ' '. $messageData['link'];

			if(isset($payload['picture']) && $payload['picture'] != '')
			{
				$messageData['type'] = 'image';
				$messageData['pic'] = $picture;
			}
			else if(trim($messageData['link']) && 'http://' != $messageData['link'])
			{
				$messageData['type'] = 'link';
			}
			else
			{
				$messageData['type'] = 'status';
			}
		}


		// Load the object
		if($payload['sns'] == SOCIAL_NETWORK_WECHAT)
		{
			$this->loadWechatAccount(NULL, $payload['ef_universe_id']);
		}
		else
		{
			$rawAccounts = $this->getAccountByEF($payload['ef_user_id'], $payload['ef_universe_id'], $payload['sns']);
			$rawAccount = array_pop($rawAccounts);

			$this->loadFromRawObject($rawAccount);
		}
		

		// Call method
		
		$result = $this->postStatus($messageData);

		return $result;
	}



	public function api_postStatusTest()
	{
		//Get API arguments
		$fvPayload = fv('payload');

		echo '<br />##### What SNSGW received($_GET["payload"] or $_POST["payload"]):<br />';
		var_dump($fvPayload);


		if($fvPayload == '')
		{
			echo '{"error":"-3","errmsg":" \'payload\' not defined or it is null"}';
			exit;
		}


		// slog('The payload What SNSGW received:');
		// slog($fvPayload);
		
		
    	$payload = str_replace(array("\r\n","\r". "\n"), '', $fvPayload);

		$payload = json_decode(fv('payload', true), true);


		// slog('payload array:');
		// slog($payload);
		echo '<br />##### payload array:<br />';
		var_dump($payload);


		if($payload == NULL)
		{
			echo '<br />{"error":"-4","errmsg":" The\'payload\' is a illegal JSON","payload":'.$fvPayload.'}<br />';
			exit;
		}

		$errmsgs = array();

		if(isset($payload['sns']) && $payload['sns'] == SOCIAL_NETWORK_WECHAT)
		{

			if(!isset($payload['articles']) || $payload['articles'] == ''){
				$errmsgs['articles'] = array('errcode'=>'-6','errmsg' => 'Not found articles');
			}
			if(!isset($payload['ef_sending_id']) || $payload['ef_sending_id'] == ''){
				$errmsgs['ef_sending_id'] = array('errcode'=>'-7','errmsg' => 'Not found ef_sending_id');
			}
			if(!isset($payload['group_id']) || $payload['group_id'] == ''){
				$errmsgs['group_id'] = array('errcode'=>'-8','errmsg' => 'Not found group_id');
			}
			if(!isset($payload['ef_universe_id']) || $payload['ef_universe_id'] == ''){
				$errmsgs['ef_universe_id'] = array('errcode'=>'-9','errmsg' => 'Not found ef_universe_id');
			}
			if(!isset($payload['msgtype']) || $payload['msgtype'] == ''){
				$errmsgs['msgtype'] = array('errcode'=>'-10','errmsg' => 'Not found msgtype');
			}
		}
		else
		{
			$errmsgs['sns'] = array('errcode'=>'-5','errmsg' => 'Not found sns');
		}

		if(!empty($errmsgs))
		{
			echo json_encode($errmsgs);
			exit;
		}
		
		exit;
	}


	/**
	 *
	 */

	public function api_disconnect()
	{
		$payload = json_decode(fv('payload', true), true);

		if(isset($payload['sns']) && $payload['sns'] == SOCIAL_NETWORK_WECHAT)
		{
			$rawAccounts = $this->find
			(
				array
				(
					'conditions' =>  array 
					(
						'wechatAppId' => array(EQUAL, $payload['appId']),
						'socialNetwork' => array(EQUAL, $payload['sns']),
						'universe' => array(EQUAL, $payload['ef_universe_id'])
					)
				)
			);
		}
		else
		{
			$rawAccounts = $this->find
			(
				array
				(
					'conditions' =>  array 
					(
						'efId' => array(EQUAL, $payload['ef_user_id']),
						'socialNetwork' => array(EQUAL, $payload['sns']),
						'universe' => array(EQUAL, $payload['ef_universe_id'])
					)
				)
			);
		}

		$result = array();

		foreach ($rawAccounts as $rawAccount)
		{
			// Extract the account

			$this->loadFromRawObject($rawAccount);

			$response = $this->getSocialNetworkDriver()->disconnect($this);
			
			$this->delete();

			$result = $response;
		}

		echo json_encode($result, JSON_FORCE_OBJECT);
		exit;
	}


	/**
	 *
	 */
	
	public function api_startConnection()
	{
		// Get API arguments
		$payload = json_decode(fv('payload', true), true);

		if($payload['sns'] == SOCIAL_NETWORK_WECHAT)
		{
			$payload['ef_user_id'] = '*';

			if(!array_key_exists('appId', $payload))
			{
				$payload['appId'] = fv('appId', true);
			}
			
			if(!array_key_exists('appSecret', $payload))
			{
				$payload['appSecret'] = fv('appSecret', true);
			}
		}

		// Call the method

		$result = $this->startConnection($payload);

		if($payload['sns'] == SOCIAL_NETWORK_WECHAT)
		{
			echo $result;
			exit;
		}
		else
		{
			redirect($result);
		}
	}


	/**
	 *
	 */

	public function api_updateStatus()
	{
		// Get API arguments

		$dataToEngage = array();

		$payload = json_decode(fv('payload', true), true);

		$efId = $payload['ef_user_id'];
		$universe = $payload['ef_universe_id'];
		$socialNetwork = $payload['sns'];

		if($efId) {
			$rawAccounts = $this->getAccountByEF($efId, $universe, $socialNetwork);
		} else {
			$rawAccounts = $this->find();
		}

		foreach ($rawAccounts as $rawAccount) {
			$this->reset();
			$this->loadFromRawObject($rawAccount);

			$result = $this->updateStatus();

			if(!empty($result))
				$dataToEngage[] = $result;
		}

		return $dataToEngage;
	}


	/**
	 * Creates properties of a CAccount
	 */
	
	protected function createProperties()
	{
		$this->createProperty
		(
			'internalId',
			array
			(
				'type' => TYPE_STRING_LONG
			)
		);

		$this->createProperty
		(
			'efId',
			array
			(
				'type' => TYPE_STRING_LONG
			)
		);

		$this->createProperty
		(
			'privateApiToken',
			array
			(
				'type' => TYPE_TEXT_SHORT
			)
		);

		$this->createProperty
		(
			'publicApiToken',
			array
			(
				'type' => TYPE_STRING_LONG
			)
		);		
		
		$this->createProperty
		(
			'refreshToken',
			array
			(
				'type' => TYPE_STRING_LONG
			)
		);

		$this->createProperty
		(
			'wechatAppId',
			array
			(
				'isRequired' => true,
				'type' => TYPE_STRING_LONG
			)
		);

		$this->createProperty
		(
			'wechatAppSecret',
			array
			(
				'isRequired' => true,
				'type' => TYPE_STRING_LONG
			)
		);

		$this->createProperty
		(
			'socialNetwork',
			array
			(
				'type' => TYPE_STRING_SHORT
			)
		);

		$this->createProperty
		(
			'universe',
			array
			(
				'isRequired' => true,
				'type' => TYPE_STRING_SHORT
			)
		);

		$this->createProperty
		(
			'urlToEf',
			array
			(
				'type' => TYPE_STRING_LONG
			)
		);

		$this->createProperty
		(
			'screenName',
			array
			(
				'type' => TYPE_STRING_SHORT
			)
		);

		$this->createProperty
		(
			'avatar',
			array
			(
				'type' => TYPE_STRING_LONG
			)
		);

		$this->createProperty
		(
			'followersCount',
			array
			(
				'type' => TYPE_STRING_LONG
			)
		);

		$this->createProperty
		(
			'friendsCount',
			array
			(
				'type' => TYPE_STRING_LONG
			)
		);

		$this->createProperty
		(
			'statusesCount',
			array
			(
				'type' => TYPE_STRING_LONG
			)
		);

		$this->createProperty
		(
			'timeOfExpirationOfApiToken',
			array
			(
				'type' => TYPE_TIMESTAMP
			)
		);

		$this->createProperty
		(
			'timeOfExpirationOfRefreshToken',
			array
			(
				'type' => TYPE_TIMESTAMP
			)
		);

		$this->createProperty
		(
			'validationApiToken',
			array
			(
				'type' => TYPE_STRING_LONG
			)
		);
	}


	/**
	 *
	 */

	public function completeConnection($params = null)
	{
		// Ask the driver to complete the connection

		$result = $this->getSocialNetworkDriver()->completeConnection($this);

		$this->setIsTemporary(0);
		$this->save();

		//$redirectUrl = pref('[Loop]/url/to/emailforge/domain') . $this->getUniverse() . pref('[Loop]/url/to/emailforge/social/page') . '?' . http_build_query($result);

		$redirectUrl = $this->getUrlToEf() . '?' . http_build_query($result);

		return $redirectUrl;
	}


	/**
	 *
	 */

	public function getSocialNetworkDriver()
	{
		// Get the classname

		$socialNetwork = $this->getSocialNetwork();
		$className = 'C' . ucfirst($socialNetwork) . 'Driver';

		// Do we support this social network?

		$pathToFile = PATH_APPLICATION . 'Class/' . $className . '.php';

		if (file_exists($pathToFile) == false)
		{
			e
			(
				EXCEPTION_SOCIAL_NETWORK_NOT_SUPPORTED,
				array
				(
					'socialNetwork' => $socialNetwork
				)
			);
		}

		// Create the driver

		require_once($pathToFile);
		$className = __NAMESPACE__.'\\'.$className;

		$socialNetworkDriver = new $className();

		return $socialNetworkDriver;
	}


	/**
	 *
	 *
	 */

	public function getGroups($appId, $universe, $socialNetwork)
	{

		$result = array();

		$rawAccounts = $this->find
		(
			array
			(
				'conditions' => array
				(
					'wechatAppId' => array(EQUAL, $appId),
					'universe' => array(EQUAL, $universe),
					'socialNetwork' => array(EQUAL, $socialNetwork)
				)
			)
		);

		
		$rawAccount = array_pop($rawAccounts);

		$this->loadFromRawObject($rawAccount);

		$result = $this->getSocialNetworkDriver()->getGroups($this);

		return $result;
	}


	/**
	 *
	 */

	public function getStatuses()
	{

		require_once(PATH_APPLICATION . 'Model/CPostStatus.php');

		$status = new CPostStatus();

		$result = $status->find(
					array
					(
						'conditions' => array
						(
							'accountId' => array(EQUAL,  $this->getInternalId()),
							'socialNetwork' => array(EQUAL,  $this->getSocialNetwork())
						)
					)
			);

		return $result;
	}


	/**
	 *
	 */

	public function startConnection($payload)
	{
		// Is the social network supported?

		if (in_array($payload['sns'], pref('[Snsfg]/socialNetworks')) == false)
		{
			e
			(
				EXCEPTION_SOCIAL_NETWORK_NOT_SUPPORTED,
				array
				(
					'socialNetwork' => $payload['sns']
				)
			);			
		}

		// Create an account
		if($payload['sns'] == SOCIAL_NETWORK_WECHAT)
		{
			$this->loadWechatAccount($payload['appId'],$payload['ef_universe_id']);
			$this->setWechatAppId($payload['appId']);
			$this->setWechatAppSecret($payload['appSecret']);
		}
		else
		{
			$this->setUrlToEf($payload['urlToEf']);
		}

		$this->setEfId($payload['ef_user_id']);
		$this->setSocialNetwork($payload['sns']);
		$this->setUniverse($payload['ef_universe_id']);
		$this->setIsTemporary(true);



		$this->save();

		// Create the right driver and ask it to start the connection

		$socialNetworkDriver = $this->getSocialNetworkDriver();

		$urlOfNextStep = $socialNetworkDriver->startConnection($this);
		
		
		return $urlOfNextStep;
	}


	/**
	 *
	 */

	public function postStatus($messageData)
	{

		$result = $this->getSocialNetworkDriver()->postStatus($this, $messageData);

		return $result;
	}


	/**
	 *
	 */

	public function updateStatus()
	{
		// Get the social network driver

		$socialNetworkDriver = $this->getSocialNetworkDriver();

		// Update statuses

		$result = $socialNetworkDriver->updateStatus($this);

		return $result;
	}


	/**
	 * Return if the social network user internalId alreadey exists in database
	 */

	public function loadAccount($idType, $id, $socialNetwork)
	{

		$rawAccounts = $this->find
		(
			array
			(
				'acceptTemporaryObjects' => true,
				'conditions' =>  array 
				(
					$idType => array(EQUAL, $id),
					'socialNetwork' => array(EQUAL, $socialNetwork)
				),
				'orderBy' => array('timeOfCreation'),
				'orderDirection' => 'ascendent'
			)
		);	

		$nbAccounts = count($rawAccounts);

		if ($nbAccounts == 1)
		{
			// Extract the account

			$rawAccount = array_pop($rawAccounts);

			$this->loadFromRawObject($rawAccount);

		}
		else if ($nbAccounts >= 1)
		{

			//Extract the oldest account

			$rawAccount = array_shift($rawAccounts);
			$this->loadFromRawObject($rawAccount);

		}

		return $this;
		
	}

	public function loadWechatAccount($appId = NULL, $universe)
	{
		if($appId != NULL)
		{
			$rawAccounts = $this->find
			(
				array
				(
					'acceptTemporaryObjects' => true,
					'conditions' =>  array 
					(
						'wechatAppId' => array(EQUAL, $appId),
						'universe' => array(EQUAL, $universe),
						'socialNetwork' => array(EQUAL, SOCIAL_NETWORK_WECHAT)
					),
					'orderBy' => array('timeOfCreation'),
					'orderDirection' => 'ascendent'
				)
			);
		}
		else
		{
			$rawAccounts = $this->find
			(
				array
				(
					'acceptTemporaryObjects' => true,
					'conditions' =>  array 
					(
						'universe' => array(EQUAL, $universe),
						'socialNetwork' => array(EQUAL, SOCIAL_NETWORK_WECHAT)
					),
					'orderBy' => array('timeOfCreation'),
					'orderDirection' => 'ascendent'
				)
			);
		}
			

		$nbAccounts = count($rawAccounts);

		if ($nbAccounts == 1)
		{
			// Extract the account

			$rawAccount = array_pop($rawAccounts);

			$this->loadFromRawObject($rawAccount);

		}
		else if ($nbAccounts >= 1)
		{

			//Extract the oldest account

			$rawAccount = array_shift($rawAccounts);
			$this->loadFromRawObject($rawAccount);

		}

		return $this;
		
	}

	public function getAccountByEF($efId, $universe, $socialNetwork = NULL)
	{
		if($socialNetwork != NULL) {
			$rawAccounts = $this->find
			(
				array
				(
					'conditions' =>  array 
					(
						'efId' => array(EQUAL, $efId),
						'universe' => array(EQUAL, $universe),
						'socialNetwork' => array(EQUAL, $socialNetwork)
					)
				)
			);
		} else {
			$rawAccounts = $this->find
			(
				array
				(
					'conditions' =>  array 
					(
						'efId' => array(EQUAL, $efId),
						'universe' => array(EQUAL, $universe)
					)
				)
			);
		}

		return $rawAccounts;
	}




	/**************************************************************
	 *
	 *	使用特定function对数组中所有元素做处理
	 *	@param	string	&$array		要处理的字符串
	 *	@param	string	$function	要执行的函数
	 *	@return boolean	$apply_to_keys_also		是否也应用到key上
	 *	@access public
	 *
	 *************************************************************/
	public function arrayRecursive(&$array, $function, $apply_to_keys_also = false)
	{
	    static $recursive_counter = 0;
	    if (++$recursive_counter > 1000) {
	        die('possible deep recursion attack');
	    }
	    foreach ($array as $key => $value) {
	        if (is_array($value)) {
	            $this->arrayRecursive($array[$key], $function, $apply_to_keys_also);
	        } else {
	            $array[$key] = $function($value);
	        }
	 
	        if ($apply_to_keys_also && is_string($key)) {
	            $new_key = $function($key);
	            if ($new_key != $key) {
	                $array[$new_key] = $array[$key];
	                unset($array[$key]);
	            }
	        }
	    }
	    $recursive_counter--;
	}
	 
	/**************************************************************
	 *
	 *	将数组转换为JSON字符串（兼容中文）
	 *	@param	array	$array		要转换的数组
	 *	@return string		转换得到的json字符串
	 *	@access public
	 *
	 *************************************************************/
	public function JSON($array) {
		$this->arrayRecursive($array, 'urlencode', true);
		$json = json_encode($array);
		return urldecode($json);
	}

	
	
}


?>
